<?php


function convertXmlObjToArr( $obj, &$arr )
{
	$children = $obj->children();
	$executed = false;
	foreach ($children as $elementName => $node)
	{
		if(is_array($arr)){
			if( array_key_exists( $elementName , $arr ) ){
				if(array_key_exists( 0 ,$arr[$elementName] ) ){
					$i = count($arr[$elementName]);
					convertXmlObjToArr ($node, $arr[$elementName][$i]);
				}else{
					$tmp = $arr[$elementName];
					$arr[$elementName] = array();
					$arr[$elementName][0] = $tmp;
					$i = count($arr[$elementName]);
					convertXmlObjToArr($node, $arr[$elementName][$i]);
				}
			}else{
				$arr[$elementName] = array();
				convertXmlObjToArr($node, $arr[$elementName]);
			}
		}else{
			$arr[$elementName] = array();
			convertXmlObjToArr($node, $arr[$elementName]);
		}
		$executed = true;
	}
	if(!$executed && $children->getName()==""){
		$arr = (String)$obj;
	}
	return ;
}



function getClassForXml($xmlArr){
	$myClass = new Classe();
	$isInError = false;
	$messageError = "";
	$attributeArray = array();
	$primaryKey = "";
	$foreignKey = array();
	$indexForeignKey = 0;
	//	foreach (array_keys($xmlArr) as $key){
	//		echo "<br>".$key." - ".$xmlArr[$key];
	//	}
	//	foreach ($xmlArr as $arr)
	foreach (array_keys($xmlArr) as $keyXML)
	{
		if($keyXML == 'name'){ //Récupération du nom de la classe
			$myClass->setNomClasse($xmlArr[$keyXML]);
		}else if($keyXML == 'exportInForm'){
			if($xmlArr[$keyXML] == "true"){
				$myClass->setExportInForm(true);
			}
		}else if($keyXML == 'attribute'){
			$arr = $xmlArr[$keyXML];
			if(is_array($arr)){
				for ($j = 0; $j < sizeof($arr); $j++) {
					$array = $arr[$j];
					if(is_array($array)){
						//liste des attributs
						//Vérification qu'il y a une balise <name></name> => Obligatoire
						if(array_key_exists('name', $array) == false){
							$messageError = "Veuillez indiquer le paramètre &lt;name&gt;&lt;/name&gt;";
							$isInError = true;
							break;
						}
						//Vérification qu'il y a une balise <type></type> => Obligatoire
						if(array_key_exists('type', $array) == false){
							$messageError = "Veuillez indiquer le paramètre &lt;type&gt;&lt;/type&gt; pour l'attribut ".$array['name'];
							$isInError = true;
							break;
						}

						$nameAttribute ="";
						$detailAttribute =array();
						$anAttribute = new Attribute();
						$index=0;
						//Récupération des attributs
						foreach (array_keys($array) as $key){
							if($key == 'name'){  //Récupération du nom de l'attribut
								$anAttribute->setName($array[$key]);
							}else if($key == 'type'){  //Récupération du type de l'attribut
								$anAttribute->setType($array[$key]);
							}else if($key == 'typeSize'){  //Récupération de la longueur du type de l'attribut
								$anAttribute->setTypeSize($array[$key]);
							}else if($key == 'primaryKey'){	//Récupération de la clé primaire si il y a la balise <primaryKey>true</primaryKey>
								if($array[$key] == "true"){
									$anAttribute->setIsPrimaryKey(true);
									$myClass->addPrimaryKey($anAttribute->getName(),$anAttribute->getName());
								}
							}else if($key == 'foreignKey'){
								//Récupération de la clé secondaire si il y a la balise <foreignKey>true</foreignKey>
								if($array[$key] == "true"){
									//Vérification qu'il a la référence de la clé secondaire <foreignKeyReference></foreignKeyReference>
									if(array_key_exists('foreignKeyForTable', $array)){
										$foreignKey[$indexForeignKey]="(`".$nameAttribute."`) references ".$array['foreignKeyForTable']."(`".$nameAttribute."`)";
										$indexForeignKey ++;
									}else{
										$messageError = "Veuillez indiquer le paramètre &lt;foreignKeyForTable&gt;&lt;/foreignKeyForTable&gt;, correspondant à la table contenant la clé étrangère. ";
										$isInError = true;
									}
								}
							}else if($key == 'canBeNull'){  //Récupération si le champs peut être NULL
								$anAttribute->setIsNull($array[$key]);
							}else if($key == 'autoincrement'){  //Récupération si le champs est auto_incrémenté
								$anAttribute->setIsAutoincrement($array[$key]);
							}else if($key == 'comment'){  //Récupération si le champs est auto_incrémenté
								$anAttribute->setComment($array[$key]);
							}else if($key == 'possibleValue'){  //Récupération des valeurs possibles du champs
								$anAttribute->setPossibleValue($array[$key]);
							}else if($key == 'isHidden'){  //Récupération si le champs doit etre camouflé
								$anAttribute->setIsHidden($array[$key]);
							}else if($key == 'exportInForm'){  //Récupération si le champs doit etre dans le formulaire
								$anAttribute->setExportInForm($array[$key]);
							}else{
								$messageError = "Balise inconnue : ".$key." !!".
								$isInError = true;
							}
						}
						if(is_array($attributeArray)){
							//Vérification que l'attribut renseigné n'existe pas déjà
							if(array_key_exists($nameAttribute, $attributeArray) == true){
								$messageError = "Le nom ".$nameAttribute." existe déjà".
								$isInError = true;
							}else{
								$myClass->addAttribute($anAttribute->getName(),$anAttribute);
								$attributeArray[$anAttribute->getName()] = $anAttribute->getName();
							}
						}
					}
				}
				$indexAttribute ++;
			}
		}else{
			echo "Erreur : Balise inconnue : ".$keyXML;
		}
	}

	//Si il y a une erreur, on créé une nouvelle classe et on indique seulement l'erreur et le message d'erreur
	if($isInError == true){
		$myClass = new Classe();
		$myClass->setHasError(true);
		$myClass->setMessageError($messageError);
	}else{
		//sinon on rempli la classe avec les données du fichier XML
		$myClass->setForeignKeys($foreignKey);
	}

	return $myClass;
}





/*
 * Vieille version de getClassForXML (à effacer plus tard, si on est OK avec la nouvelle version de la méthode et du fichier XML)

 function getClassForXml($xmlArr){
 $myClass = new Classe();
 $isInError = false;
 $messageError = "";
 $attributeArray = array();
 $primaryKey = "";
 $foreignKey = array();
 $indexForeignKey = 0;
 foreach ($xmlArr as $arr)
 {
 //Le premier paramètre n'est pas un tableau, c'est la balise <name></name> qui correspond donc
 // au nom de la classe
 //Le 2ème paramètre est un tableau contenant les attributs
 if(is_array($arr)){
 for ($j = 0; $j < sizeof($arr); $j++) {
 $array = $arr[$j];
 if(is_array($array)){
 //liste des attributs
 //Vérification qu'il y a une balise <name></name> => Obligatoire
 if(array_key_exists('name', $array) == false){
 $messageError = "Veuillez indiquer le paramètre &lt;name&gt;&lt;/name&gt;";
 $isInError = true;
 break;
 }
 //Vérification qu'il y a une balise <type></type> => Obligatoire
 if(array_key_exists('type', $array) == false){
 $messageError = "Veuillez indiquer le paramètre &lt;type&gt;&lt;/type&gt; pour l'attribut ".$array['name'];
 $isInError = true;
 break;
 }
 $nameAttribute ="";
 $detailAttribute =array();
 $index=0;
 //Récupération des attributs
 foreach (array_keys($array) as $key){
 if($key == 'name'){
 //Récupération du nom de l'attribut
 $nameAttribute = $array[$key];
 }else if($key == 'primaryKey'){
 //Récupération de la clé primaire si il y a la balise <primaryKey>true</primaryKey>
 if($array[$key] == "true"){
 //Vérification que la clé primaire n'est pas déja renseignée (sinon, on la sauve dans une variable)
 if($primaryKey != ""){
 $messageError = "La clé primaire a déja été déclarée : ".$primaryKey." VS ".$nameAttribute;
 $isInError = true;
 }else{
 $primaryKey = $nameAttribute;
 }
 }
 }else if($key == 'foreignKey'){
 //Récupération de la clé secondaire si il y a la balise <foreignKey>true</foreignKey>
 if($array[$key] == "true"){
 //Vérification qu'il a la référence de la clé secondaire <foreignKeyReference></foreignKeyReference>
 if(array_key_exists('foreignKeyReference', $array)){
 $foreignKey[$indexForeignKey]="(`".$nameAttribute."`) references ".$array['foreignKeyReference']."(`".$nameAttribute."`)";
 $indexForeignKey ++;
 }else{
 $messageError = "Veuillez indiquer le paramètre &lt;foreignKeyReference&gt;&lt;/foreignKeyReference&gt;, correspondant à la table contenant la clé étrangère. ";
 $isInError = true;
 }
 }
 }else{
 //On sauvegarde les paramètres de l'attribut (sauf la foreignKeyReference)
 if($key != 'foreignKeyReference'){
 $detailAttribute[$index] = $array[$key];
 $index ++;
 }
 }
 }
 if(is_array($attributeArray)){
 //Vérification que l'attribut renseigné n'existe pas déjà
 if(array_key_exists($nameAttribute, $attributeArray) == true){
 $messageError = "Le nom ".$nameAttribute." existe déjà".
 $isInError = true;
 }else{
 $attributeArray[$nameAttribute] = $detailAttribute;
 }
 }
 }
 }
 $indexAttribute ++;
 }else{
 //Nom de la classe
 $className = $arr;
 $myClass->setNomClasse($className);
 }
 }

 //Si il y a une erreur, on créé une nouvelle classe et on indique seulement l'erreur et le message d'erreur
 if($isInError == true){
 $myClass = new Classe();
 $myClass->setHasError(true);
 $myClass->setMessageError($messageError);
 }else{
 //sinon on rempli la classe avec les données du fichier XML
 $myClass->setPrimaryKey($primaryKey);
 $myClass->setAttributes($attributeArray);
 $myClass->setForeignKeys($foreignKey);
 }

 return $myClass;
 }
 */
//ATTENTION --> Méthode à changer de place et à refaire !!!!!!
//Vérification que la classe renseignée en paramètre n'existe pas déja en DB
function existInDB($nomClasse){
	$dbtype="mysql";
	$user="admin";
	$pass="admin";
	$host="localhost";
	$dbname="lptsite";


	$connection = mysql_connect($host,$user,$pass);
	if ( ! $connection )
	die ("connection impossible");

	mysql_select_db($dbname) or die ("pas de connection, table inexistante...");
	$query = "SELECT COUNT(*) FROM $nomClasse";
	$result = mysql_query($query);
	$num_rows = @mysql_num_rows($result);

	if($num_rows)
	return TRUE;
	else
	return FALSE;
}


//ATTENTION --> Méthode à changer de place et à refaire !!!!!!
//Méthode d'exécution d'une requète passée en paramètre
function createInDB($request){
	$dbtype="mysql";
	$user="admin";
	$pass="admin";
	$host="localhost";
	$dbname="lptsite";

	$connection = mysql_connect($host,$user,$pass);
	if ( ! $connection )
	die ("connection impossible");
	//echo $request;
	mysql_select_db($dbname) or die ("pas de connection, DB inexistante...");
	$result = mysql_query($request);
	if($result == 0){
		echo $request;
		return FALSE;
	}
	return TRUE;
}

//Méthode pour créer le model xxx.class.php à partir de la classe 'Classe' fournie en paramètre
function createModelFromClasse($aClasse){
	$nameOfClasse = $aClasse->getNomClasse();
	$fileName = "../../model/".$nameOfClasse.".class.php";
	if(file_exists($fp)){
		unlink($fp);
	}
	$fp = fopen($fileName,"w");
	fputs($fp, "<?php");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "// ******************************************************************************\n");
	fputs($fp, "// Cette classe est auto-générée! Merci de ne pas faire de modification dedans !!\n");
	fputs($fp, "// ******************************************************************************\n");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "class ".ucfirst($nameOfClasse)." {");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	$allAttributes = $aClasse->getAttributes();
	//déclaration des attributs
	foreach ( $allAttributes as $attribute){
		fputs($fp, "    private \$".$attribute->getName()."; \n");
	}
	
	fputs($fp, "    \n");
	fputs($fp, "    public function __construct() {\n");
	fputs($fp, "    }\n");
	

	//création des getters / setters
	foreach ( $allAttributes as $attribute){
		fputs($fp, "\n"); // on va a la ligne
		fputs($fp, "    public function get".ucfirst($attribute->getName())."() { \n");
		fputs($fp, "       return \$this->".$attribute->getName()."; \n");
		fputs($fp, "    } \n");
		fputs($fp, "\n"); // on va a la ligne
		fputs($fp, "    public function set".ucfirst($attribute->getName())."(\$".$attribute->getName().") { \n");
		fputs($fp, "       \$this->".$attribute->getName()." = \$".$attribute->getName()."; \n");
		fputs($fp, "    } \n");
	}
	
	fputs($fp, "\n"); // on va a la ligne
	//Méthode de mapping permettant de remplir les attributs de la classe avec l'attribut 'row
	//qui correspond à une ligne de la DB
	fputs($fp, "    public function doMapping(\$row) { \n");
	foreach ( $allAttributes as $attribute){
		fputs($fp, "       \$this->".$attribute->getName()." = \$row['".$attribute->getName()."'] "); 
		fputs($fp, "\n"); // on va a la ligne
	}
	fputs($fp, "    } \n");
	
	
	
	
	fputs($fp, " } \n");
	fputs($fp, "?>");
	fclose($fp);
}



function createFormFromClasse($aClasse){
	$nameOfClasse = $aClasse->getNomClasse()."Form";
	$object = $aClasse->getNomClasse();
	$fileName = "../../lib/form/".$nameOfClasse.".class.php";
	if(file_exists($fp)){
		unlink($fp);
	}
	$fp = fopen($fileName,"w");
	fputs($fp, "<?php");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "// ******************************************************************************\n");
	fputs($fp, "// Cette classe est auto-générée! Merci de ne pas faire de modification dedans !!\n");
	fputs($fp, "// ******************************************************************************\n");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "class ".ucfirst($nameOfClasse)." {");
	fputs($fp, "\n"); // on va a la ligne
	fputs($fp, "\n"); // on va a la ligne
	
	fputs($fp, "public function __construct() {\n");
	fputs($fp, "}\n");
	fputs($fp, "\n");
	
	
	fputs($fp, "public function get".ucfirst($nameOfClasse)."(\$linkForm, \$".$object.") {\n");
	fputs($fp, " \$body .=\" \n");
	
	
	fputs($fp, "<form method=POST action=\\\"\".\$linkForm.\"\\\" > \n");
	
	
	$allAttributes = $aClasse->getAttributes();
	//déclaration des attributs
	fputs($fp, "\n<table>");
	foreach ( $allAttributes as $attribute){
		if($attribute->getExportInForm() == "true"){
			$typeInput = "";
			$input = "";
			///// pour les types TEXT
			if($attribute->getType() == 'VARCHAR'
			|| $attribute->getType() == 'INT'
			|| $attribute->getType() == 'SMALLINT'
			|| $attribute->getType() == 'TEXT'
			|| $attribute->getType() == 'CHAR'
			|| $attribute->getType() == 'DECIMAL'
			|| $attribute->getType() == 'DATE'
			){
				if($attribute->getIsHidden()){
					$typeInput = "password";
				}else{
					$typeInput = "text";
				}
				$input =" <input type=".$typeInput." name=".$attribute->getName()." value=\\\"\".\$".$object."->get".ucfirst($attribute->getName())."().\"\\\" >";
			}else if($attribute->getType() == 'BOOLEAN'){
				$input .=" ".$val."<input type=checkbox name=".$attribute->getName()." value=\\\"\".\$".$object."->get".ucfirst($attribute->getName())."().\"\\\" >";
			}else if($attribute->getType() == 'ENUM' || $attribute->getType() == 'SET'){
				$allValues = explode(",",$attribute->getPossibleValue());
				foreach ($allValues as $val){
					$input .=" ".$val."<input type=radio name=".$attribute->getName()." value=\\\"\".\$".$object."->get".ucfirst($attribute->getName())."().\"\\\" >";
				}
			}
			
			
			
			fputs($fp, "\n<tr><td>");
			fputs($fp, " <label for=\\\"".$attribute->getName()."\\\" >".$attribute->getComment()."</label>");
			fputs($fp, "\n</td><td>");
			fputs($fp, $input);
			fputs($fp, "\n</td></tr>");
		}
	}
	
	fputs($fp, "\n</table>");
	
	fputs($fp, "</form>");
	
	
	fputs($fp, " \"; \n");
	fputs($fp, "\n");
	fputs($fp, " return \$body;\n");
	fputs($fp, "}\n");

	fputs($fp, "?>");
	fclose($fp);
}


?>